<template>
  <div class="article-preview">
    <!-- 目录切换按钮 - 桌面端显示为侧边栏，移动端显示为浮动按钮 -->
    <div
      class="article-preview__catalog-toggle"
      :class="{ 'is-active': showCatalog }"
      @click.stop="toggleCatalog"
    >
      <div class="article-preview__toggle-icon">
        <el-icon><Menu /></el-icon>
      </div>
      <span class="article-preview__toggle-text">目录</span>
    </div>

    <!-- 文章预览区域 -->
    <div class="article-preview__container">
      <MdPreview
        :modelValue="article.content"
        :preview-theme="previewTheme"
        :code-theme="codeTheme"
        :show-code-row-number="true"
        :id="previewId"
        :showToc="false"
        :noMermaid="false"
      />
    </div>

    <!-- 目录抽屉 - 从右侧滑入 -->
    <div class="article-preview__catalog" :class="{ 'is-visible': showCatalog }" @click.stop>
      <div class="article-preview__catalog-header">
        <h3>文章目录</h3>
        <el-icon class="article-preview__close-icon" @click="closeCatalog"><Close /></el-icon>
      </div>

      <MdCatalog
        :editorId="previewId"
        class="article-preview__catalog-content"
        :theme="theme"
        scrollElement=".layout__content"
        :scrollElementOffsetTop="60"
        :scrollBehavior="'smooth'"
        :scrollContainer="true"
      />
    </div>
  </div>
</template>

<script setup>
/**
 * 文章预览页面组件
 *
 * 功能：
 * 1. 使用Markdown格式展示文章内容
 * 2. 可切换显示文章目录
 * 3. 响应式设计，支持移动端和桌面端
 * 4. 根据文章ID加载文章内容
 */
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Menu, Close } from '@element-plus/icons-vue'
import { MdPreview, MdCatalog } from 'md-editor-v3'
import 'md-editor-v3/lib/preview.css'
import { articleApi } from '@/api/article'

// =============== 状态与配置 ===============

/**
 * 路由和状态
 */
const route = useRoute()
const article = ref({})
const showCatalog = ref(false)

/**
 * 预览器配置
 * 控制Markdown预览的样式和行为
 */
const previewId = 'preview-article' // 预览器ID，用于目录联动
const previewTheme = 'vuepress' // 预览主题样式
const codeTheme = 'atom' // 代码块主题样式
const theme = 'light' // 整体主题

// =============== 方法 ===============

/**
 * 切换目录显示状态
 * 显示或隐藏文章目录
 */
const toggleCatalog = () => {
  showCatalog.value = !showCatalog.value
}

/**
 * 关闭目录
 * 隐藏文章目录
 */
const closeCatalog = () => {
  showCatalog.value = false
}

/**
 * 处理点击外部区域事件
 * 当点击目录和切换按钮之外的区域时关闭目录
 * @param {Event} e - 点击事件对象
 */
const handleClickOutside = (e) => {
  const catalogWrapper = document.querySelector('.article-preview__catalog')
  const catalogToggle = document.querySelector('.article-preview__catalog-toggle')
  if (
    showCatalog.value &&
    !catalogWrapper?.contains(e.target) &&
    !catalogToggle?.contains(e.target)
  ) {
    closeCatalog()
  }
}

/**
 * 获取文章详情
 * 根据路由参数加载文章数据
 */
const fetchArticleDetail = async () => {
  try {
    const { id } = route.params
    if (!id) {
      ElMessage.error('文章ID不能为空')
      return
    }

    const data = await articleApi.getDetail(id)
    if (data) {
      article.value = data
      document.title = `${data.title} - 文章预览`
    } else {
      ElMessage.error('文章不存在')
    }
  } catch (error) {
    console.error('获取文章详情失败:', error)
    ElMessage.error('获取文章详情失败')
  }
}

// =============== 生命周期 ===============

/**
 * 组件挂载后
 * 加载文章数据并添加点击事件监听
 */
onMounted(() => {
  fetchArticleDetail()
  document.addEventListener('click', handleClickOutside)
})

/**
 * 组件卸载前
 * 移除事件监听
 */
onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
})
</script>

<style lang="scss" scoped>
// 导入主题变量和混合器
@use '@/assets/styles/theme/base.scss' as *;
@use '@/assets/styles/mixins.scss' as *;

/**
 * 文章预览组件样式
 * 使用BEM命名规范
 */
.article-preview {
  padding: 24px;
  min-height: calc(100vh - 60px);
  background-color: $bg-base;
  position: relative;

  /**
   * 目录切换按钮
   * 桌面端显示为侧边固定按钮
   */
  &__catalog-toggle {
    position: fixed;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    height: 90px;
    width: 32px;
    background-color: $color-primary;
    color: white;
    border-radius: $radius-large 0 0 $radius-large;
    cursor: pointer;
    @include flex-center;
    flex-direction: column;
    gap: 8px;
    padding: 12px 0;
    @include transition(all);
    @include box-shadow('light');
    z-index: 11;

    // 悬浮效果
    &:hover {
      width: 36px;
      background-color: rgba($color-primary, 0.9);
    }

    // 激活状态
    &.is-active {
      .article-preview__toggle-icon .el-icon {
        transform: rotate(-90deg);
      }
    }
  }

  /**
   * 切换按钮图标
   */
  &__toggle-icon {
    @include flex-center;

    .el-icon {
      font-size: 20px;
      @include transition(transform);
    }
  }

  /**
   * 切换按钮文字
   */
  &__toggle-text {
    writing-mode: vertical-lr;
    font-size: $font-size-small;
    letter-spacing: 2px;
  }

  /**
   * 预览内容容器
   */
  &__container {
    width: 100%;
    max-width: 900px;
    margin: 0 auto;

    :deep(.md-preview) {
      background-color: $bg-base;
      box-shadow: none;
      padding: 0;

      .md-preview-wrapper {
        padding: 0;
      }
    }
  }

  /**
   * 目录抽屉
   */
  &__catalog {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 300px;
    background-color: $bg-base;
    @include box-shadow('medium');
    transform: translateX(100%);
    @include transition(transform);
    z-index: 99;
    display: flex;
    flex-direction: column;

    // 显示状态
    &.is-visible {
      transform: translateX(0);
    }
  }

  /**
   * 目录头部
   */
  &__catalog-header {
    height: 60px;
    padding: 0 20px;
    border-bottom: 1px solid $border-light;
    @include flex-between;

    h3 {
      font-size: $font-size-body;
      font-weight: 500;
      color: $text-primary;
    }
  }

  /**
   * 关闭图标
   */
  &__close-icon {
    font-size: 20px;
    cursor: pointer;
    color: $text-secondary;
    padding: 4px;
    border-radius: $radius-base;
    @include transition;

    &:hover {
      color: $text-primary;
      background-color: $bg-light;
    }
  }

  /**
   * 目录内容
   */
  &__catalog-content {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
    @include custom-scrollbar;

    :deep(.md-catalog-list) {
      .md-catalog-item {
        margin: 8px 0;

        // 目录项链接
        a {
          display: block;
          padding: 10px 18px;
          color: $text-regular;
          font-size: 16px;
          line-height: 1.8;
          border-radius: $radius-medium;
          font-weight: 500;
          letter-spacing: 0.5px;
          @include transition;

          &:hover {
            color: $color-primary;
            background-color: rgba($color-primary, 0.08);
            font-weight: 600;
          }
        }

        // 激活状态
        &.active > a {
          color: #fff;
          background-color: $color-primary;
          font-weight: 700;
        }

        // 二级及更深层级目录样式
        .md-catalog-item {
          margin-left: 18px;
          a {
            font-size: 15px;
            font-weight: 400;
            padding: 8px 16px;
          }
        }
      }
    }
  }

  /**
   * 响应式布局适配
   */
  @include respond-to('sm') {
    // 移动端按钮样式
    &__catalog-toggle {
      top: auto;
      bottom: 20px;
      right: 20px;
      height: 48px;
      width: 48px;
      border-radius: 50%;
      flex-direction: row;
      padding: 0;

      .article-preview__toggle-text {
        display: none;
      }

      &:hover {
        width: 48px;
        transform: scale(1.1) translateY(-50%);
      }
    }

    // 移动端目录宽度
    &__catalog {
      width: 85%;
    }
  }
}
</style>
